package com.appspot.android2gather.server;

import static com.appspot.android2gather.server.ActivityManager.checkParameters;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.persistence.EntityManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.appspot.android2gather.activity.ErrorMessage;
import com.appspot.android2gather.persistance.ActivityEntity;
import com.appspot.android2gather.persistance.EMF;
import com.appspot.android2gather.persistance.PMF;
import com.beoui.geocell.GeocellManager;
import com.beoui.geocell.model.GeocellQuery;
import com.beoui.geocell.model.Point;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gson.Gson;
import static com.appspot.android2gather.activity.RequestParameters.*;

public class ActivitySearch extends HttpServlet {

	/**
     * 
     */
	private static final long serialVersionUID = -3377133496584535831L;
	private static Gson gson = new Gson();

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		if (req.getParameterMap().size() == 0) {
			getUserActivities(req, resp);
			return;
		}
		// check params
		ArrayList<ErrorMessage> errors = checkParameters(req, LONGITUDE,
				LATITUDE);
		Double longitude, latitude;
		int range, maxResults;
		if (errors.size() > 0) {
			resp.getWriter().write(
					gson.toJson(errors.toArray(), ErrorMessage[].class));
			return;
		}
		// check coordinates
		try {
			latitude = Double.parseDouble(req.getParameter(LATITUDE));
			longitude = Double.parseDouble(req.getParameter(LONGITUDE));
		} catch (NumberFormatException nfe) {
			resp.getWriter().write(
					gson.toJson(new ErrorMessage("Invalid coordinates.")));
			return;
		}
		// check range
		if (assigned(RANGE)) {
			try {
				range = Integer.parseInt(req.getParameter(RANGE));
			} catch (NumberFormatException nfe) {
				resp.getWriter().write(
						gson.toJson(new ErrorMessage("Invalid range.")));
				return;
			}
		} else {
			range = 10000; // default value
		}

		// check range
		try {
			maxResults = Integer.parseInt(req.getParameter(MAXRESULTS));
		} catch (NumberFormatException nfe) {
			maxResults = 20; // assume default value
		}

		// build query string
		PersistenceManager pm = PMF.get().getPersistenceManager();

		try {
			Point center = new Point(latitude, longitude);

			List<Object> params = new ArrayList<Object>();
			GeocellQuery baseQuery;
			params.add(System.currentTimeMillis());
			baseQuery = new GeocellQuery("endTime > currentTime",
					"long currentTime", params); // activities that
													// haven't ended yet.

			List<ActivityEntity> results = null;
			results = GeocellManager.proximityFetch(center, maxResults, range,
					ActivityEntity.class, baseQuery, pm);
			// write activities
			resp.getWriter().write(
					gson.toJson(results.toArray(), ActivityEntity[].class));
		} finally {
			pm.close();

		}

	}

	/**
	 * Get all Activites that belong to the logged in user
	 * 
	 * @param req
	 * @param resp
	 */
	@SuppressWarnings("unchecked")
	private void getUserActivities(HttpServletRequest req,
			HttpServletResponse resp) throws ServletException, IOException {
		List<ActivityEntity> results = null;

		/*
		 * try { javax.persistence.Query createQuery = em.createQuery(
		 * "SELECT FROM ActivityEntity AS e WHERE e.creator=:creator AND e.endTime>:currentTime"
		 * ); createQuery.setParameter("creator",
		 * UserServiceFactory.getUserService().getCurrentUser() );
		 * createQuery.setParameter("currentTime" , System.currentTimeMillis());
		 * results = (List<ActivityEntity> )createQuery.getResultList(); }
		 * finally { em.close(); }
		 */
		User currentUser = UserServiceFactory.getUserService().getCurrentUser();
		PersistenceManager pm = PMF.get().getPersistenceManager();

		try { 
			Query query = pm.newQuery(ActivityEntity.class);
			query.setFilter("endTime>" + System.currentTimeMillis() +" && creator==creatorParam");
			//query.declareImports("com.google.appengine.api.users.User");
			query.declareParameters("com.google.appengine.api.users.User creatorParam");
			
			results = (List<ActivityEntity>) query.execute(UserServiceFactory.getUserService().getCurrentUser() );
			resp.getWriter().write(
					new Gson().toJson(results.toArray(), ActivityEntity[].class));
		} finally {
			pm.close();
		}

	

		return;
	}

	public static void main(String[] args) {
		System.out.println(System.currentTimeMillis());
	}
}
